﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

namespace TronLeapRacing
{
    class MotorCycle : GameObject
    {
        float rotation;
        float angle;

        bool ende = false;
        bool pause = false;

        GameTime gametime;
        Control control;
        private int attempts;
        Matrix world;

        Model shadow;

        SoundEffect crashSound;

        public MotorCycle(Control control)
            : base()
        {
            this.control = control;

            world = Matrix.CreateRotationX(-1.57f + angle) * Matrix.CreateScale(0.8f) * Matrix.CreateTranslation(position);
        }

        //Läd den Inhalt und erstellt BoundingSphere
        public void LoadContent(ContentManager Content, string name)
        {
            model = Content.Load<Model>(name);
            shadow = Content.Load<Model>("Models/cycleShadow");
            boundingSphere = calculateBoundingSphere();

            crashSound = Content.Load<SoundEffect>("Music/crash");
            BoundingSphere scaledSphere;
            scaledSphere = boundingSphere;

            boundingSphere = new BoundingSphere(scaledSphere.Center, scaledSphere.Radius);
        }

        //Ubdatet die Positon des Models
        public void Update(GameTime gametime, Barrier[] barriers, BoundingBox[] boundingBox)
        {
            world = Matrix.CreateRotationX(-1.57f + angle) * Matrix.CreateScale(0.8f) * Matrix.CreateTranslation(position);

            this.gametime = gametime;
            if (!ende && !pause)
            {
                control.Update(gametime);
                control.move();
                boundingSphere.Center = position;
                movement(control.coord, barriers, boundingBox);
            }
        }

        //Bewegt die BoudningSphere mit dem Model
        private bool movement(Vector3 futurePosition, Barrier[] barriers, BoundingBox[] boundingBox)
        {
            BoundingSphere futureBoundingSphere = boundingSphere;
            futureBoundingSphere.Center = futurePosition;
            if (barrierCollision(futureBoundingSphere, barriers, boundingBox))
            {
                return false;
            }
            position = control.coord;
            return true;
        }

        //Fragt ab ob das Model mit einem Hindernis Kolidiert
        private bool barrierCollision(BoundingSphere motorcycleBoundingSphere, Barrier[] barriers, BoundingBox[] boundingBox)
        {
            for (int currentBarrier = 0; currentBarrier < boundingBox.Length; currentBarrier++)
            {
                if (motorcycleBoundingSphere.Intersects(boundingBox[currentBarrier]))
                {
                    control.coord.X -= 30;
                    control.coord.Z = 0;
                    position = control.coord;
                    countattempts();

                    crashSound.Play();

                    return true;
                }
            }
            return false;
        }

        //zählt die Anzhal der Versuche und Setzt das Model zurück zum Anfang
        public void countattempts()
        {
            attempts++;
            control.coord = Vector3.Zero;
            control.rotation = 0;
            control.angle = 0;
        }

        //gbt die Anzahl der Versuche zurück
        public int getattempts()
        {
            return attempts;
        }

        //gibt an das das Spiel beendet ist
        public void setEnde(bool ende)
        {
            this.ende = ende;
            control.setEnde(ende);
        }

        //Setzt den GameState auf Pause
        public void setPause(bool pause)
        {
            this.pause = pause;
            control.setPause(pause);
        }

        //Gibt zurueck ob das Spiel Beendet ist
        public bool getEnde()
        {
            return ende;
        }

        //Zeichnet das Model
        public void Draw(float rotation, float angle, Matrix view, Matrix projection)
        {
            this.rotation = rotation;
            this.angle = angle;

                foreach (ModelMesh mesh in model.Meshes)
                {
                    foreach (BasicEffect effect in mesh.Effects)
                    {
                        effect.EnableDefaultLighting();
                        effect.World = world;
                        effect.Projection = projection;
                        effect.View = view;
                    }
                    mesh.Draw();
                }
                control.Draw(gametime);
        }

        public void DrawShadow(float rotation, float angle, Matrix view, Matrix projection)
        {
            this.rotation = rotation;
            this.angle = angle;

            Plane lightPlane = new Plane(Vector3.UnitY, 0);
            Vector3 lightPos = new Vector3(10f, 10f, 2f);

            Matrix shadowMatrix = Matrix.CreateShadow(Vector3.Normalize(lightPos), lightPlane);
            Matrix worldshadow = world * shadowMatrix;

            foreach (ModelMesh mesh in shadow.Meshes)
            {
                foreach (BasicEffect effect in mesh.Effects)
                {
                    effect.LightingEnabled = false;
                    effect.World = worldshadow;
                    effect.Projection = projection;
                    effect.View = view;

                }
                mesh.Draw();
            }
            control.Draw(gametime);
        }

        //Zeichnet die Boundingsphere
        /*internal void DrawBoundingSphere(Matrix view, Matrix projection, GameObject boundingSphereModel)
        {
            foreach (ModelMesh mesh in boundingSphereModel.model.Meshes)
            {
                foreach (BasicEffect effect in mesh.Effects)
                {
                    effect.World = Matrix.CreateRotationZ(rotation) * Matrix.CreateTranslation(new Vector3(0, 1, 0)) * Matrix.CreateRotationX(angle) * Matrix.CreateTranslation(boundingSphere.Center);
                    effect.View = view;
                    effect.Projection = projection;
                }
                mesh.Draw();
            }
        }
        */
    }
}
